package com.zzj.security.jwt.config;

import com.alibaba.druid.pool.DruidDataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.persistence.EntityManagerFactory;
import javax.sql.DataSource;
import java.util.Properties;

/**
 * @ClassName EntityManagerInitialize
 * @Description TODO
 * @Author zhijun zeng at 17:39 2020/5/17
 * @Version 1.0
 **/
@Configuration
@EnableTransactionManagement
@PropertySource(value = { "classpath:application.properties" })
public class EntityManagerInitialize {

    public static final Logger logger = LoggerFactory.getLogger(EntityManagerInitialize.class);

    @Autowired
    private Environment environment;

    @Bean(name="entityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean(){
        LocalContainerEntityManagerFactoryBean entityManagerFactory =
                new LocalContainerEntityManagerFactoryBean();
        entityManagerFactory.setDataSource(dataSource());
        /*
         * 没有 配置 JPA 提供商的适配器 的话,会报如下错误
         * No PersistenceProvider specified in EntityManagerFactory configuration,
         * and chosen PersistenceUnitInfo does not specify a provider class name either
         * */
        entityManagerFactory.setJpaVendorAdapter(jpaVendorAdapter());//配置 JPA 提供商的适配器
        entityManagerFactory.setPackagesToScan(new String[]{"com.zzj.security.jwt.entity"});//配置扫描@Entity注解实体类所在的包
        entityManagerFactory.setJpaProperties(jpaProperties());//配置 或 下述配置
        // 或下述配置 下述配置好像无法自动创建表
        //spring.jpa.properties.hibernate.show_sql=true
        //spring.jpa.properties.hibernate.format_sql=true
        //spring.jpa.properties.hibernate.ddl-auto=update
        return entityManagerFactory;
    }

    @Bean(name="dataSource")
    public DataSource dataSource(){
        //DriverManagerDataSource dataSource = new DriverManagerDataSource();
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setDriverClassName(environment.getRequiredProperty("spring.datasource.driver-class-name"));
        dataSource.setUrl(environment.getRequiredProperty("spring.datasource.url"));
        dataSource.setUsername(environment.getRequiredProperty("spring.datasource.username"));
        dataSource.setPassword(environment.getRequiredProperty("spring.datasource.password"));
        logger.info("=== driverClassName:{}",environment.getRequiredProperty("spring.datasource.driver-class-name"));
        logger.info("=== url:{}",environment.getRequiredProperty("spring.datasource.url"));
        logger.info("=== username:{}",environment.getRequiredProperty("spring.datasource.username"));
        logger.info("=== password:{}",environment.getRequiredProperty("spring.datasource.password"));
        return dataSource;
    }

    /**
     * 配置 JPA 提供商的适配器
     * */
    @Bean
    public JpaVendorAdapter jpaVendorAdapter(){
        JpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter();
        return jpaVendorAdapter;
    }

    //未使用到的配置信息
//			jdbc.driverClassName = com.mysql.jdbc.Driver
//			jdbc.url = jdbc:mysql://localhost:3306/yiibai
//			jdbc.username = root
//			jdbc.password =
//			hibernate.dialect = org.hibernate.dialect.MySQLDialect
//			hibernate.show_sql = true
//			hibernate.format_sql = true
    private Properties jpaProperties(){
        Properties properties = new Properties();
        //设置各种属性
//		properties.put("spring.jpa.database",
//				environment.getRequiredProperty("spring.jpa.database"));
//		properties.put("spring.jpa.generate-ddl",
//				environment.getRequiredProperty("spring.jpa.generate-ddl"));
//		properties.put("spring.jpa.properties.hibernate.show_sql",
//				environment.getRequiredProperty("spring.jpa.properties.hibernate.show_sql"));
//		properties.put("spring.jpa.properties.hibernate.format_sql",
//				environment.getRequiredProperty("spring.jpa.properties.hibernate.format_sql"));
//		properties.put("spring.jpa.properties.hibernate.ddl-auto",
//				environment.getRequiredProperty("spring.jpa.properties.hibernate.ddl-auto"));
//		properties.put("spring.jpa.properties.hibernate.dialect",
//				environment.getRequiredProperty("spring.jpa.properties.hibernate.dialect"));
//		properties.put("spring.jpa.properties.hibernate.naming-strategy",
//				environment.getRequiredProperty("spring.jpa.properties.hibernate.naming-strategy"));

        //使用如下可以创建表,使用上述则无法创建
        properties.put("hibernate.hbm2ddl.auto",
                environment.getRequiredProperty("hibernate.hbm2ddl.auto"));
        properties.put("hibernate.show_sql",
                environment.getRequiredProperty("hibernate.show_sql"));
        properties.put("hibernate.format_sql",
                environment.getRequiredProperty("hibernate.format_sql"));
        properties.put("hibernate.dialect",
                environment.getRequiredProperty("hibernate.dialect"));
        return properties;
    }

    @Bean(name="transactionManager")
    @Autowired
    public JpaTransactionManager transactionManager(EntityManagerFactory entityManagerFactory){
        JpaTransactionManager transactionManager = new JpaTransactionManager();
        transactionManager.setEntityManagerFactory(entityManagerFactory);
        return transactionManager;
    }

}